<template>
  <!-- start -->

  <div class="progress-content">
    <!-- 日志类型 -->
    <div class="page-right-search" v-if="isShowFilter" :class="{'page-right-search-user': isFromUserView}">
      <div>
        <span class="search-label">{{ $t('common.label.recordType') }}：</span>
        <div>
          <el-select
            v-model="recordsSelect"
            @change="selectChange"
            :placeholder="$t('common.placeholder.selectWorkStatus')"
          >
            <el-option
              v-for="item in selectList"
              :key="item.key"
              :label="item.name"
              :value="item.key"
            >
              {{ item.name }}
            </el-option>
          </el-select>
        </div>
      </div>

      <!-- 生成日期 -->
      <div>
        <span class="search-label">{{ $t('common.label.genTime') }}：</span>
        <div>
          <el-date-picker
            v-model="datePicker"
            style="width: 100%;"
            type="daterange"
            align="right"
            unlink-panels
            range-separator="-"
            :start-placeholder="$t('common.base.startDate')"
            :end-placeholder="$t('common.base.endDate')"
            value-format="timestamp"
            @change="searchRecord"
            :default-time="['00:00:00', '23:59:59']">
          </el-date-picker>
        </div>
      </div>

      <el-button v-if="showExportBtn && isNotUserRecord" type="primary" @click="exportRecords()">{{ $t('common.base.export') }}</el-button>
      <el-tooltip v-if="isFromUserView && isShowTrack && _isShowTaskModule" :content="$t('common.map.showPointCount', { count: 30 })">
        <el-button type="primary" @click="trackMapClickHandler()">{{ $t('common.map.showTrack') }}</el-button>
      </el-tooltip>
    </div>

    <div class="task-info-record">
      <!-- start 时间轴 -->
      <div class="task-timeline" ref="timeline">
        <base-timeline
          :data="recordPage.list"
          :record-render="renderRecord"
          :loading="recordLoading"
          :loadmore="showLoadmore"
          @load="loadmore"
        />
        <NoAuth v-show="(!recordPage || !recordPage.list || !recordPage.list.length ) && !recordLoading"></NoAuth>
      </div>
      <!-- end 时间轴 -->
    </div>

    <el-dialog :title="$t('common.map.taskTrack')" :visible.sync="showTrackMap" width="900px" @close="reset">
      <div class="base-modal-content">
        <!-- 内容主体区域 -->
        <bbx-power-map v-if="currentMapType" :current-map-type="currentMapType" ref="baseMapCon" />
        <div class="track-container">
          <el-radio-group v-model="status" @change="getTaskOrUserRecord">
            <el-radio-button label="taskRecord">{{ $t('common.label.taskPosition') }}</el-radio-button>
            <el-radio-button label="userRecord">{{ $t('common.label.workStatus') }}</el-radio-button>
          </el-radio-group>

          <div v-for="(item, index) in trackList" :key="item.id" class="track-map-list-item" @click.stop="showMarkerModal(index)">
            <div class="track-map-list-item-inner">
              <div class="track-map-list-icon-view">{{index + 1}}</div>
              <div v-if="item.cusName" class="track-map-l-i-title">{{item.cusName}}</div>
              <div v-if="item.taskNo" class="track-map-l-i-row">
                <span class="track-map-l-i-key">{{ $t('common.label.task') }}：</span>
                <span @click.stop="openTaskViewByTrackMap(item.taskId)" class="track-map-l-i-link">
                  {{item.taskNo}}
                </span>
              </div>
              <div class="track-map-l-i-row">
                <span class="track-map-l-i-key">{{ $t('common.label.time') }}：</span>
                <span class="track-map-l-i-value">{{item.createTime | fmt_datetime}}</span>
              </div>
              <div class="track-map-l-i-row">
                <span class="track-map-l-i-key">{{ $t('common.label.node') }}：</span>
                <span class="track-map-l-i-value">{{item.action || ''}}</span>
              </div>
              <div class="track-map-l-i-row">
                <span class="track-map-l-i-key">{{ $t('common.label.address') }}：</span>
                <span class="track-map-l-i-value">{{item.address || ''}}</span>
              </div>
              <div class="track-map-l-i-line"></div>
            </div>
          </div>

        </div>

      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="showTrackMap = false">{{ $t('common.base.close') }}</el-button>
      </div>
    </el-dialog>
    <!-- start 人员卡片 -->
    <biz-user-card ref="userCard"></biz-user-card>
    <!-- end 人员卡片 -->
    <div class="base-export-bridge" ref="bridge"></div>
  </div>
  <!-- end -->
</template>

<script>
/* api */
import * as DeptHomeApi from '@src/api/DeptHomeApi';
/* utils */
import _ from "lodash";
import { safeNewDate } from '@src/util/time';
import Page from "@model/Page";
import { openTabForEventView, openTabForTaskView } from "@src/util/business/openTab";
/* enum */
import { TaskEventNameMappingEnum } from '@model/enum/EventNameMappingEnum.ts';

import { isBasicEditionHideEvent, isOnlyCustomerServiceCloudVersion } from '@shb-lib/version';
/* mixin */
import AuthMixin from '@src/mixins/authMixin'
import { ConnectorModuleConnectorRecordMixin, ConnectorModuleTriggerRecordMixin } from '@src/modules/connector'
import addressMixin from '@src/mixins/addressMixin';

import { trimAll, formatDate, objectToUrlParams } from 'pub-bbx-utils'

function createAttachmentDom(h, attachments) {
  return attachments && attachments.length > 0 ? (
    <div class="base-timeline-attachment base-file__preview">
      {attachments.map((item) => (
        <base-file-item
          Source={attachments}
          file={item}
          key={item.id}
          readonly
          size="small"
        />
      ))}
    </div>
  ) : (
    ''
  );
}

function createLinkDom(h, s){
  const reg = /((((https?|ftp?):(?:\/\/)?)(?:[-;:&=\+\$]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\?\+=&;:%!\/@.\w_]*)#?(?:[-\+=&;%!\?\/@.\w_]*))?)/g;
  const str = s.replace(reg, (str) => `@#@${str}@#@`);
  const arr = str.split('@#@');
  return (
    <p class="pre-line secondary-info">
      {arr.map((item) => {
        if (item.indexOf('http') === 0) {
          return (
            <a href={item} target="_blank">
              {item}
            </a>
          );
        }
        return <biz-comment-html html={item}></biz-comment-html>;
      })}
    </p>
  );
}
import { isOpenData, openAccurateTab } from '@src/util/platform';
import { t } from '@src/locales'
import { translateAction } from '@src/util/record'
// 暂无数据组件
import NoAuth from '@src/modules/dept/user/components/NoAuth.vue'
let map = null;
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum'
import { useNewVue } from '@hooks/useNewVue'
const { extendVue } = useNewVue();
import { useMapType } from '@src/util/map';
import { MapTypeEnum } from '@model/enum/MapEnum'
/* mixin */
import { VersionControlTaskMixin } from '@src/mixins/versionControlMixin';

export default {
  name: 'dept-records',
  inject: ['initData'],
  mixins: [
      AuthMixin,
      ConnectorModuleConnectorRecordMixin,
      ConnectorModuleTriggerRecordMixin,
      addressMixin,
      VersionControlTaskMixin
  ],
  components:{
    NoAuth,
  },
  props: {
    showTemplate: {
      type: Boolean,
      default: true,
    },
    shareData: {
      type: Object,
      default: () => ({}),
    },
    detailId: {
      type: String,
      default: ''
    },
    displayName: {
      type: String,
      default: ''
    },
    isFromUserView: {
      type: Boolean,
      default: false,
    },
    isShowTrack: {
      type: Boolean,
      default: false,
    },
    showExportBtn:{
      type:Boolean,
      default: false,
    },
    // 是否显示头部过滤 -- 首页会调用 不需要头部过滤
    isShowFilter: {
      type: Boolean,
      default: true,
    }
  },
  data() {
    return {
      showTrackMap: false,
      status: 'taskRecord',
      trackList: [],

      isOpenData,
      commentPending: false,
      params: {
        pageNum: 1,
        pageSize: 15,
      },
      recordLoading: false,
      recordPage: new Page(),

      // 选择
      recordsSelect: 'all',
      datePicker: [],
      pickerOptions: {
        // 不能选择今天之后的日期
        disabledDate(d){
          if(d > safeNewDate()){
            return true
          }
          return false
        }
      },
      showLoadmore: true,
      exportAction: '',
      portUrl:'',
      currentMapType:null
    };
  },
  computed: {
    address() {
      return this.shareData?.address || '';
    },
    auth() {
      return this.shareData?.auth || {};
    },
    isArchive() {
      return this.shareData?.isArchive || false;
    },
    // 权限
    authorities() {
      let user = this.loginUser || {};
      return user.authorities || {};
    },
    allTaskEdit() {
      return this.authorities['TASK_EDIT'] === 3;
    },
    /** 是否允许操作 */
    allowOperate() {
      return this.task?.isDelete === 0;
    },
    /** 查看单权限 */
    allowTaskView() {
      return this.initData?.canViewTask === true;
    },
    customer() {
      return this.task?.customer || {};
    },
    /** 添加备注权限 */
    editComment() {
      return this.allowTaskView && this.allowOperate;
    },
    loginUser() {
      return this.initData?.loginUser || {};
    },
    linkman() {
      return this.shareData?.linkman || {};
    },
    task() {
      return this.shareData?.task || {};
    },
    taskId() {
      return this.task?.id;
    },
    taskNo() {
      return this.task?.taskNo;
    },
    remarkTemplateList() {
      return this.showTemplate ? this.initData.remarkList : [];
    },
    // 基础版功能隐藏事件
    isBasicEditionHideEvent() {
      return isBasicEditionHideEvent();
    },
    // 请求不同接口 判断是否是工作状态
    isState() {
      return this.recordsSelect === 'state';
    },
    // 选择框数据
    selectList() {
      const arr = [
        { name: t('common.base.all'), key: 'all', show: true },
        { name: t('common.label.workStatus'), key: 'state', show: true},
        { name: t('common.label.taskRemark'), key: 'type', show: this._isShowTaskModule },
        { name: t('common.label.taskRecord'), key: 'log', show: this._isShowTaskModule },
        { name: t('common.label.taskPosition'), key: 'location', show: this._isShowTaskModule },
        { name: t('common.label.staffRecord'), key: 'userRecord', show: true}
      ];
      return arr.filter(item => item.show)
    },
    // 时间变化
    initDate(){
      const [createTimeStart, createTimeEnd] = this.datePicker || []
      return {
        createTimeStart,
        createTimeEnd,
      }
    },
    isNotUserRecord(){
      // 暂时不加人员导出功能
      return this.recordsSelect !== 'userRecord'
    }
  },
  async mounted() {
    const { currentMapType } = await useMapType();
    this.currentMapType = currentMapType()
    this.initializeRecord();
    this.$eventBus.$on(
      TaskEventNameMappingEnum.UpdateRecord,
      this.searchRecord
    );
    this.$eventBus.$on('comment-user-card', this.handleUserCard)
    this.exportAction = `/security/user/taskRecord/export?userId=${this.detailId}`;
  },
  beforeDestroy() {
    this.$eventBus.$off(
      TaskEventNameMappingEnum.UpdateRecord,
      this.searchRecord
    );
    this.$eventBus.$off('comment-user-card', this.handleUserCard)
  },
  methods: {
    handleUserCard(event){
      this.$refs.userCard.open(event)
    },
    // 显示轨迹
    trackMapClickHandler(){
      this.showTrackMap = true;
      this.getTaskOrUserRecord('taskRecord')
    },
    createMarker() {
      let markerList = []
      this.trackList.forEach((item, index)=> {
        const useSize = new AMap.Pixel(18, 26);
        const useBgUrl = 'https://cloud.shb.ltd/resource/images/trackmap_location_index_icon.png';
        const useOrderIndex = index + 1;
        const this_ = this;
        const useContent = {
          render(h){
            return(
              <div class="track-map-marker-icon-dom" style={`width: ${ useSize.x || 18 }px;height: ${ useSize.y || 26 }px;background: url(${ useBgUrl })`}>
                <span class="track-map-marker-icon-index">{ useOrderIndex }</span>
              </div>
            )
          }
        };
        const infoWindow = {
          render(h) {
            return (
              <div class="bg-w pad-12 min-w-250">
                <p class="track-map-inner-title">{ item.cusName || '' }</p>
                { item.taskNo && <div class="track-map-inner-row"><span class="track-map-inner-label">{this_.$t('common.base.task')}： </span><span onClick={(e)=>{this_.openTaskViewByTrackMap(item.taskId)}} class="track-map-inner-link">{ item.taskNo }</span></div>}
                <div class="track-map-inner-row"><span class="track-map-inner-label">{this_.$t('common.base.time')}： </span><span class="track-map-inner-value">{ formatDate(item.createTime) }</span></div>
                <div class="track-map-inner-row"><span class="track-map-inner-label">{this_.$t('common.base.node')}： </span><span class="track-map-inner-value">{ item.action }</span></div>
                <div class="track-map-inner-row"><span class="track-map-inner-label">{this_.$t('common.base.address')}： </span><span class="track-map-inner-value">{ item.address }</span></div>

              </div>
            );
          }
        };
        const markCon = extendVue(useContent)
        const windowCon = extendVue(infoWindow);
        let obj = {
          markInfo:markCon,
          size:{
            x:18,
            y:26
          },
          showInfoWindowType:'click',
          infoWindow:windowCon,
          lng:item.longitude,
          lat:item.latitude
        }
        markerList.push(obj)
      })

      this.$refs.baseMapCon.setListMark(markerList)
      this.$refs.baseMapCon.drawPolyline()
    },
    showMarkerModal(index) {
      this.$refs.baseMapCon.openInfoWindow({ mapIndex:index })
    },
    getLatAndLongList(result) {
      return result.map((item)=> {
        return [item.longitude, item.latitude]
      })
    },
    openTaskViewByTrackMap(taskId){
      openTabForTaskView(taskId)
    },
    getTaskOrUserRecord(type){
      let action = `/security/user/trail/${type}`;
      this.$http.get(action, {userId: this.detailId}).then(result=>{
        this.trackList = (result || []).map(item=>{
          item.createTime = formatDate(item.createTime)
          return item
        })
        this.$nextTick(()=>{
          this.createMarker()
        })
      })
    },
    reset(){
      this.trackList = []
      this.status = 'taskRecord'
    },
    /**
     * 同时满足以下条件允许删除该记录
     * 1. 该记录没有被删除
     * 2. 工单编辑权限（CUSTOMER_EDIT）值为3 或者 是创建人
     * 3. 该工单没有被删除
     */
    allowDeleteRecord(item) {
      let isDelete = item.content.isDelete == 'true';
      let user = this.loginUser;
      let isCreator = item.userId == user.userId;

      return !isDelete && (this.allTaskEdit || isCreator) && this.allowOperate;
    },
    /**
     * @description 抓取信息动态
     */
    fetchRecord(params) {
      const api = this.isState
        ? DeptHomeApi.getDeptUserRecords
        : DeptHomeApi.getDeptMyTaskRecords;

      return api(params).then((data) => {
        return { result: { list: data } };
      });
    },
    /**
     * @description 初始化信息动态
     */
    async initializeRecord() {
      this.params.pageNum = 1;
      this.searchRecord();
    },
    /**
     * @description 加载下一页
     */
    async loadmore() {
      try {
        this.params.pageNum++;
        this.recordLoading = true;

        let params = {
          ...this.params,
          ...this.initDate,

        }
        if(this.isFromUserView) {
          params.userId = this.detailId
        }else {
          params.tagId = this.detailId
        }

        let data = await this.fetchRecord(params);
        if(data.result.list.length < 15){
          this.showLoadmore = false;
        }

        this.recordLoading = false;
        this.recordPage.merge(data.result);
      } catch (error) {
        console.warn('loadmore -> error', error);
      }
    },


    recordPageListConvertHandler(list = []) {
      list.forEach((record) => {
        try {
          record.attachments = JSON.parse(record.attachments);
        } catch (error) {
          console.warn('searchRecord  recordPage.list.forEach -> error', error);
        }
      });
    },
    /**
     * @description 渲染地址dom
     * @param {Object} record 记录数据
     * @param {Boolean} isFinished 是否是完成状态 特殊处理
     */
    renderAddressRecordDom(record = {}, isFinished = false) {
      let address = trimAll(record.address || '');
      let { latitude, longitude } = record;
      let isShowAddress = address && latitude && longitude;
      let openMapFunc = isFinished ? this.openMapForFinished : this.openMap;
      let icon = isShowAddress ? <i class="iconfont icon-address"></i> : '';
      let addressDom = (
        <span
          onClick={(e) => {
            openMapFunc(record);
          }}
        >
          {icon}
          {address}
        </span>
      );
      return { address, icon, isShowAddress, addressDom };
    },
    /* 渲染工单编号 */
    renderTaskNo(taskNo, taskId){
      const className = this.globalIsHaveTaskViewDetailAuth ? 'task-no-link': ''
      return (
        <span onClick={() => this.openTaskTab(taskNo, taskId)} class={className}>
          #{taskNo}
        </span>
      )
    },
    /* 打开工单页面 */
    openTaskTab(taskNo, taskId) {
      if (!taskId) return;

      if (!this.globalIsHaveTaskViewDetailAuth) return

      openAccurateTab({
        type:PageRoutesTypeEnum.PageTaskView,
        key:taskId,
        params:'noHistory=1'
      });
    },
    /* 渲染指派转派 */
    renderAllotDom(record = {}) {
      let { action, userName, content, taskNo, taskId, executorName, staffId, executorStaffId, userId, executorId } = record;
      return (
        <div class="task-record-allot">
          <h5>
            <i18n path="department.deptRecords.taskCareOf">
              <span place="user1">{this.renderUserName(userName, staffId, userId)}</span>
              <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
              <span place="action">{translateAction(action)}</span>
              <span place="user2">{this.renderUserName(executorName, executorStaffId, executorId)}。</span>
            </i18n>

          </h5>
          {content && Object.keys(content).length > 0 && (
            <div>
              {content.synergy && <div>{this.$t('common.fields.synergies.displayName')}：{this.renderSynergyName(content.synergy, content.synergyStaffId)}</div>}
              {content.updateType == 'tRecord'
                && (action == '转派' && content.updateContent ? (
                  <div>
                    {`${this.$t('department.deptRecords.careOfDesc')}：${content.customExceptionReason}`}
                    <div>{this.$t('department.deptRecords.detailsDesc')}：<biz-comment-html html={content.updateContent}></biz-comment-html></div>
                  </div>
                ) : (
                  <div><biz-comment-html html={content.updateContent}></biz-comment-html></div>
                ))}
            </div>
          )}
        </div>
      );
    },
    /* 自定义异常 */
    abnormalRender(record = {}) {
      let { content } = record;
      return <div>{this.$t('department.deptRecords.taskAbnormal', {action: translateAction(content.action)})}</div>;
    },
    /* 渲染添加备注 */
    renderActionRemarkDom(h, record = {}) {
      let {
        userName,
        showInOwn,
        toCustomer,
        cusNotice,
        content,
        attachments,
        cusRemarksNotice,
        staffId,
        userId
      } = record;
      return [
        <h5 class="main-info">
          {this.renderUserName(userName, staffId,userId)}
          {this.$t('department.deptRecords.renderActionRemark[0]')}
          {!!showInOwn && (
            <span class="private">
              {' '}
              <i class="iconfont icon-account1"></i> {this.$t('department.deptRecords.renderActionRemark[1]')}{' '}
            </span>
          )}
          。{!!toCustomer && <span class=""> ({this.$t('department.deptRecords.renderActionRemark[2]')}) </span>}
          {!!cusNotice && cusRemarksNotice !== 1 && (
            <span class=""> ({this.$t('department.deptRecords.renderActionRemark[3]')}) </span>
          )}
          {!!cusRemarksNotice && (
            <span class=""> ({this.$t('department.deptRecords.renderActionRemark[4]')}）) </span>
          )}
        </h5>,
        content.isDelete == 'true' ? (
          <p class="text-danger">
            <i18n path="department.deptRecords.renderActionRemark[5]">
              <span place="user">{this.renderUserName(content.deleteUserName, content.deleteUserStaffId)}</span>
              <span place="time">{content.deleteTime}</span>
            </i18n>
          </p>
        ) : (
          [
            createLinkDom(h, content.updateContent),
            createAttachmentDom(h, attachments),
          ]
        ),
      ];
    },
    /* 渲染api新建 */
    renderApiCreateDom(record = {}) {
      let { userName, content, taskNo, taskId, staffId, userId } = record;
      return [
        <h5>
          <i18n path="department.deptRecords.renderApiCreate">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="client">{content.clientName}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>,
      ];
    },
    /* 渲染工单自动分配dom */
    renderTaskAutoAllotDom(record = {}) {
      let { executorName = '', content, taskNo, taskId, executorStaffId, executorId } = record;
      return (
        <div>
          <i18n path="department.deptRecords.renderTaskAutoAllot">
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="rule">{content.ruleName}</span>
            <span place="user">{this.renderUserName(executorName, executorStaffId, executorId)}</span>
          </i18n>
        </div>
      );
    },
    /* 渲染工单自动分配失败dom */
    renderTaskAutoAllotFailDom(record = {}) {
      let { content, taskNo, taskId } = record;
      return (
        <div class="task-record-fail">
          <i18n path="department.deptRecords.enderTaskAutoAllotFail">
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="fail">{content.fail}</span>
          </i18n>
        </div>
      );
    },
    /* 渲染工单自动派单dom */
    renderTaskAutoDispatchDom(record = {}) {
      let { executorName = '', content, taskNo, taskId, executorStaffId, executorId } = record;
      return (
        <div>
          <i18n path="department.deptRecords.renderTaskAutoAllot">
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="rule">{content.ruleName}</span>
            <span place="user">{this.renderUserName(executorName, executorStaffId, executorId)}</span>
          </i18n>
        </div>
      );
    },
    /* 渲染基础的工单动作 */
    renderBaseTaskAction({ action, userName, taskNo, taskId, staffId, userId }) {
      return (
        <h5>
          <i18n path="department.deptRecords.renderBaseTaskAction">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="action">{translateAction(action)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>
      );
    },
    /* 渲染留言 */
    renderLeaveMessageDom(h, record = {}) {
      let { userName, content, attachments, staffId, userId } = record;
      return [
        <h5 class="main-info">
          <i18n path="department.deptRecords.addLeaveMessage">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
          </i18n>
        </h5>,
        content.isDelete == 'true' ? (
          <p class="text-danger">
            <i18n path="department.deptRecords.deleteLeaveMessage">
              <span place="user">{this.renderUserName(content.deleteUserName, content.deleteUserStaffId)}</span>
              <span place="time">{content.deleteTime}</span>
            </i18n>
          </p>
        ) : (
          [
            <p class="pre-line secondary-info"><biz-comment-html html={content.updateContent}></biz-comment-html></p>,
            createAttachmentDom(h, attachments),
          ]
        ),
      ];
    },
    /* 渲染电话日志 */
    renderPhoneLogDom(record = {}) {
      let { userName, content, staffId, userId } = record;
      return (
        <h5>
          <i18n path="department.deptRecords.renderPhoneLog">
            <span place="user1">{this.renderUserName(userName, staffId, userId)}</span>
            <strong place="user2">{content.targetName}</strong>
          </i18n>
        </h5>
      );
    },
    /* 渲染编辑回执dom */
    renderReceiptEditDom({ userName, taskNo, taskId, staffId, userId }) {
      let addressData = this.renderAddressRecordDom(...arguments);
      return [
        <h5>
          <i18n path="common.record.task.receiptEdit">
            <span place="operator">{this.renderUserName(userName, staffId, userId)}</span>
            <strong place="taskNo">{this.renderTaskNo(taskNo, taskId)}</strong>
          </i18n>
        </h5>,
        addressData.isShowAddress ? (
          <div class="form-view-row-content-address">
            {addressData.addressDom}
          </div>
        ) : (
          ''
        ),
      ];
    },
    /* 渲染发布到工单池dom */
    renderReleaseTaksPoolDom(record = {}) {
      let { action, userName, content, taskNo, taskId, staffId, userId } = record;
      let synergyDom = content.synergy ? (
        <div>{this.$t('common.fields.synergies.displayName')}：{this.renderSynergyName(content.synergy, content.synergyStaffId)}</div>
      ) : (
        ''
      );
      let contentDom = content.toTaskPool === '1' ? (
        <p class="pre-line secondary-info">{this.$t('department.deptRecords.careOfDesc')}：<biz-comment-html html={content.updateContent}></biz-comment-html></p>
      ) : (
        <p class="pre-line secondary-info"><biz-comment-html html={content.updateContent}></biz-comment-html></p>
      );

      return [
        <h5>
          <i18n path="common.record.task.receiptEdit">
            <span place="operator">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="taskNo">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>,
        <div>
          {synergyDom}
          {content.updateType == 'tRecord' ? contentDom : ''}
        </div>,
      ];
    },
    /* 渲染开始和完成 */
    renderStartOrFinishDom(record = {}) {
      let { content, address, action } = record;
      let isFinished = action == '完成';
      let addressData = this.renderAddressRecordDom(record, isFinished);
      let isPositionException = content.isPositionException == 'true';
      let className = isPositionException ? 'task-position-exception' : '';
      let startOrFinshRecord = [
        // 基础工单操作日志
        <div> {this.renderBaseTaskAction(record)} </div>,
        // 地址操作
        <div>
          {address === 'PC端' ? (
            <span>{this.$t('department.deptRecords.optPC')}</span>
          ) : (
            <span class="form-view-row-content-address">
              {addressData.addressDom}
            </span>
          )}
        </div>,
        // 是否地理位置异常
        <div>
          {isPositionException && (
            <span>
              {this.$t('department.deptRecords.distanceCustomer')}
            {content.distance
              ? `${content.distance}km`
              : this.$t('department.deptRecords.positionError')}
            </span>
          )}
        </div>,
      ];

      return <div class={className}>{startOrFinshRecord}</div>;
    },
    /* 渲染出发 */
    renderSetOutDom(record = {}) {
      let { action, userName, taskNo, staffId, content, userId, address } = record;
      let addressData = this.renderAddressRecordDom(record);
      return (
        <div>
          <div>
            <span place="operator">{this.renderUserName(userName, staffId, userId)}</span>
            {t('task.record.setOut')}
          </div>
          <div>
            { address === 'PC端' ? <span>{t('task.record.operateFromPcEnd')}</span> : <span class="form-view-row-content-address">{ addressData.addressDom }</span> }
          </div>
        </div>
      )
    },
    /* 渲染计划任务新建工单 */
    renderPlanTaskCreateDom(record = {}) {
      let { content, taskNo, taskId } = record;
      return (
        <h5>
          <i18n path="department.deptRecords.planTaskCreate">
            <span place="plan">{content.planName}</span>
            <span place="task">{taskNo}</span>
          </i18n>
        </h5>
      );
    },
    /* 渲染工单接受dom */
    renderTaskAcceptDom(record = {}) {
      let { content, userName, action, taskNo, taskId, staffId, userId } = record;
      let fromTaskPool = content.fromTaskPool == '1';
      let taskPoolAcceptDom = (
        <h5>
          <i18n path="common.record.task.taskAcceptFromTaskPool">
            <span place="operator">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="taskNo">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>
      );

      return fromTaskPool
        ? taskPoolAcceptDom
        : this.renderBaseTaskAction(record);
    },
    /* 渲染工单审批dom */
    renderTaskApproveDom(record = {}) {
      let { content, taskNo, taskId, address, userName, longitude, latitude, staffId, userId } = record;
      let { state, level } = content;
      // 工单审批状态
      let taskState = {
        unApproved: state == 'unapproved',
        success: state == 'success',
        fail: state == 'fail',
        offed: state == 'offed',
      };
      // 工单审批等级
      let levelName = level >= 1 ? `${[t('common.base.level0'), t('common.base.level1'),t('common.base.level2'),t('common.base.level3'),t('common.base.level4'),t('common.base.level5'),t('common.base.level6'),t('common.base.level7'),t('common.base.level8'), t('common.base.level9')][level] }` : '';
      // 是否显示地址
      let isShowAddress = address && address != 'PC端';
      // 地址数据
      let addressData = this.renderAddressRecordDom(record);
      // 地址dom
      let addressDom = isShowAddress ? (
        longitude && latitude ? (
          <div class="form-view-row-content-address">
            {addressData.addressDom}
          </div>
        ) : (
          <div>{address}</div>
        )
      ) : (
        ''
      );
      // 未审批dom
      let unApprovedDom = [
        <div>
          {this.renderUserName(userName, staffId, userId)} {address == 'PC端' ? this.$t('department.deptRecords.passPC') : ''}
          <i18n path="department.deptRecords.approvedTask">
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="action">{this.getTaskAction(content)}</span>
          </i18n>
        </div>,
        content.remark && <div>{this.$t('common.base.remark')}<biz-comment-html html={content.remark}></biz-comment-html></div>,
        content.apprNames && (
          <div>
            {content.apprNames_2 ? t('common.base.approveUserLevel1') : t('common.base.approveUser')}：{this.renderSynergyName(content.apprNames, content.apprStaffIds)}
          </div>
        ),
        content.apprNames_2 && <div>{t('common.base.approveUserLevel2')}：{this.renderSynergyName(content.apprNames_2, content.apprStaffIds_2)}</div>,
        addressDom,
      ];

      // 审批成功dom
      let isAutoApprove = userName == '自动审批';
      let autoApproveDom = (
        <h5>
          <i18n path="department.deptRecords.autoApprove">
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="action">{this.getTaskAction(content)}</span>
            <span place="level">{levelName}</span>
          </i18n>
        </h5>
      );
      let notAutoApproveDom = [
        <div>
          <i18n path="department.deptRecords.notAutoApprove">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="action">{this.getTaskAction(content)}</span>
            <span place="level">{levelName}</span>
          </i18n>
        </div>,
        content.remark && <div>{this.$t('common.base.remark')}：<biz-comment-html html={content.remark}></biz-comment-html></div>,
      ];
      let successDom = isAutoApprove ? autoApproveDom : notAutoApproveDom;
      // 审批失败dom
      let failDom = [
        <div>
          <i18n path="department.deptRecords.refuseApprovedTask">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="action">{this.getTaskAction(content)}</span>
            <span place="level">{levelName}</span>
          </i18n>
        </div>,
        content.remark && <div>{this.$t('common.base.remark')}：<biz-comment-html html={content.remark}></biz-comment-html></div>,
      ];
      // 审批撤回dom
      let offedDom = [
        <div>
          <i18n path="department.deptRecords.offedApprovedTask">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="action">{this.getTaskAction(content)}</span>
          </i18n>
        </div>,
      ];

      return [
        <div>
          {taskState.unApproved ? unApprovedDom : ''}
          {taskState.success ? successDom : ''}
          {taskState.fail ? failDom : ''}
          {taskState.offed ? offedDom : ''}
        </div>,
      ];
    },
    getTaskAction(content) {
      if(content?.isNodeTask == '1'){
        return content.action
      }else {
        return translateAction(content.action)
      }
    },
    /* 渲染工单修改结算dom */
    renderTaskBalanceDom(record = {}) {
      let { content, taskNo, taskId, userName, staffId, userId } = record;
      let balanceArr = [];

      for (let name in content) {
        let value = content[name];
        if(value) {
          let arr = value.split("[ + + ]");
          let data = { name, oldValue: arr[0], newValue: arr[1] };

          balanceArr.push(data);
        }
      }

      return [
        <h5>
          <i18n path="department.deptRecords.modifyRask">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>,
        balanceArr.map((review) => {
          return (
            <div>
              <i18n path="department.deptRecords.modifyName">
                <strong place="name">{review.name}</strong>
                <strong place="old">{review.oldValue}</strong>
                <strong place="new">{review.newValue}</strong>
              </i18n>
            </div>
          );
        }),
      ];
    },
    /* 渲染工单附加组件卡片 */
    renderTaskCardDom(record = {}) {
      let { userName, content, staffId, userId } = record;
      return (
        <div>
          <i18n path="department.deptRecords.taskCard">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="action">{translateAction(content.action)}</span>
            <span place="card">{content.cardName}</span>
          </i18n>
        </div>
      );
    },
    /* 渲染工单创建dom */
    renderTaskCreatetDom(record = {}) {
      let { content = {} } = record;
      let { eventId, eventNo } = content;
      let isEventToTask = Boolean(eventId);

      return [
        this.renderBaseTaskAction(record),
        isEventToTask ? (
          this.isBasicEditionHideEvent ? (
            <span>{this.$t('department.deptRecords.taskCreate', {event: eventNo})}</span>
          ) : (
            <span onClick={(event) => openTabForEventView(eventId)}>
              <i18n path="department.deptRecords.taskCreate">
                <span place="event" class="link-text">{eventNo} </span>
              </i18n>
            </span>
          )
        ) : (
          ''
        ),
      ];
    },
    /* 渲染工单修改dom */
    renderTaskEditDom(record = {}) {
      let { content } = record;
      return [
        this.renderBaseTaskAction(record),
        content.updateFields && <div>{this.$t('common.base.modifyField')}：{content.updateFields} </div>,
        content.planTime && <div>{this.$t('common.base.planTime')}：{content.planTime} </div>,
      ];
    },
    /* 渲染工单暂停dom */
    renderTaskPausedDom(record = {}) {
      let { action, content, taskNo, taskId, userName, staffId, userId } = record;
      let customExceptionReasonDom = content.customExceptionReason && (
        <div>{this.$t('common.base.pauseReason')}：{content.customExceptionReason}</div>
      );
      let reasonDom = content.reason && <div>{this.$t('common.base.detailsReason')}：<biz-comment-html html={content.reason}></biz-comment-html></div>;
      return (
        <div class="task-record-fail">
          <div>
            <i18n path="department.deptRecords.renderBaseTaskAction">
              <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
              <span place="action">{translateAction(action)}</span>
              <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            </i18n>
          </div>
          {customExceptionReasonDom}
          {reasonDom}
        </div>
      );
    },
    /* 渲染回访短信dom */
    renderTaskCodeReviewDom(record = {}) {
      let { action, taskNo, taskId, userName, staffId, userId } = record;
      return (
        <i18n path="common.record.task.taskCodeReview" tag="h5">
          <span place="operator">{this.renderUserName(userName, staffId, userId)}</span>
          <span place="taskNo">{this.renderTaskNo(taskNo, taskId)}</span>
        </i18n>
      );
    },
    /* 渲染工单支付dom */
    renderTaskPaymentDom(record = {}) {
      let { userName, taskNo, taskId, staffId, userId } = record;
      return (
        <h5>
          <i18n path="department.deptRecords.taskCodeReview">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>
      );
    },
    /* 渲染工单回访dom */
    renderTaskReviewDom(record = {}) {
      let { content } = record;
      let degree = '';
      let tag = '';
      let star = [];
      let reviewArr = [];

      for (let name in content) {
        if(name === 'deleteUserStaffId'){
          continue
        }
        let value = content[name] || '';
        let arr = value.split('[ + + ]');
        let data = { name, oldValue: arr[0], newValue: arr[1] };
        if (name == '满意度') {
          degree = _.cloneDeep(data);
        } else if (name == '服务标签') {
          tag = _.cloneDeep(data);
        } else {
          star.push(data);
        }
      }

      if (degree) reviewArr.push(degree);
      if (star) reviewArr = reviewArr.concat(star);
      if (tag) reviewArr.push(tag);
      return [
        this.renderBaseTaskAction(record),
        reviewArr.map((review) => {
          return (
            <div>
              <i18n path="department.deptRecords.modifyName">
                <strong place="name">{review.name}</strong>
                <strong place="old"><biz-comment-html html={review.oldValue} /></strong>
                <strong place="new"><biz-comment-html html={review.newValue} /></strong>
              </i18n>
            </div>
          );
        }),
      ];
    },
    /* 渲染工单服务报告dom */
    renderTaskServiceReportDom(record = {}) {
      let { content, userName, taskNo, taskId, staffId, userId } = record;
      let path = 'department.deptRecords.taskServiceReport'
      if (content && content.operation === 'create') {
        path = 'department.deptRecords.taskServiceReport2'
      }
      return (
        <div>
          <i18n path={path}>
            <strong place="user">{this.renderUserName(userName, staffId, userId)}</strong>
            <strong place="task">{this.renderTaskNo(taskNo, taskId)}</strong>
          </i18n>
        </div>
      );
    },
    /* 渲染工单超时dom */
    renderTaskTimeoutDom(record = {}) {
      let { content } = record;
      return [
        <div>
          <i18n path="department.deptRecords.taskTimeout">
            <span place="user">{this.renderSynergyName(content.receivers, content.receiversStaffId)}</span>
          </i18n>
        </div>,
        content.flow && <div>{this.$t('common.record.processNode')}： {content.flow}</div>,
        <div>{this.$t('common.record.processTimeout')}：{content.overTime}</div>,
      ];
    },
    /* 渲染工单已超时dom */
    renderTaskTimeoutdDom(record = {}) {
      let { content, taskNo, taskId } = record;
      return (
        <div class="task-record-fail">
          <i18n path="department.deptRecords.taskTimeoutNode">
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
            <span place="node">{content.flow}</span>
          </i18n>
        </div>
      );
    },
    /* 渲染工单转交dom */
    renderTaskTransferDom(record = {}) {
      let { executorName, userName, executorId, content, taskNo, taskId, staffId, executorStaffId, userId } = record;
      return [
        <h5>
          <i18n path="department.deptRecords.taskTransfer">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>,
        executorId && <div>{this.$t('department.deptRecords.modifyExecutor')}：{this.renderUserName(executorName, executorStaffId, executorId)}</div>,
        content.synergy && <div>{this.$t('department.deptRecords.modifySynergy')}：{this.renderSynergyName(content.synergy, content.synergyStaffId)}</div>,
      ];
    },
    /* 渲染工单审批转交dom */
    renderTaskApproveTransferDom(record = {}) {
      let { operatorName, handoverName, operatorStaffId, handoverStaffId } = record?.content;
      return (
        <h5>
          <i18n path="department.deptRecords.taskApproveTransfer">
            <strong place="operator">{this.renderUserName(operatorName, operatorStaffId)}</strong>
            <strong place="handover">{this.renderUserName(handoverName, handoverStaffId)}</strong>
          </i18n>
        </h5>
      )
    },
    /* 渲染备件服务清单dom */
    renderSparepartAndServiceListDom(record = {}) {
      let { userName, content = {}, staffId, userId } = record;
      let { action, inventoryTypeName } = content;
      let partList = JSON.parse(content.partList || '[]');

      if (action == '出库申请') {
        return (
          <h5>
            <i18n path="department.deptRecords.sparepartAndService">
              <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
              <span place="inventory">{inventoryTypeName}</span>
              <span place="action">{translateAction(action)}</span>
            </i18n>
          </h5>
        );
      }

      return (
        <h5>
          <i18n path="department.deptRecords.sparepartinventory">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="inventory">{inventoryTypeName}</span>
            <span place="action">{translateAction(action)}</span>
            <span place="part">{partList.join('，')}</span>
          </i18n>
        </h5>
      );
    },
    /* 渲染备件服务清单dom */
    renderWorkingStatusDom(record = {}) {
      let { userName, content = {}, staffId, userId } = record;
      let { state } = content;

      return (
        <h5>
          <i18n path="department.deptRecords.updateWorkingStatus">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="status">{state}</span>
          </i18n>
        </h5>
      );
    },
    /* 渲染更新位置 */
    renderUpdateAddressRecord(record = {}) {
      let { userName, staffId, userId } = record;
      let addressData = this.renderAddressRecordDom(record)
      return [
        <i18n path="department.deptRecords.updateAddress" tag="h5">
          <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
        </i18n>,
        <div>
          <span class="form-view-row-content-address">{ addressData.addressDom }</span>
        </div>
      ];
    },
    /**
     * @des 添加人员信息日志
     */
    renderOperateLog(record = {}){
      let { userName, content = {}, staffId, userId, executorName, executorId, executorStaffId } = record;
      const { operationContent, action:contentAction } = content;
      let action = '';
      if(contentAction === 'reuploadFace' || contentAction == 'uploadFace'){
        return (
          <i18n path={`common.record.dept.operate['${contentAction}']`} tag="h5">
            <span place="operator">{executorStaffId ? this.renderUserName(executorName, executorStaffId, executorId) : this.renderUserName(userName, staffId, userId)}</span>
          </i18n>
        )
      }
      if(operationContent.includes('新增')){
        action = 'add'
      }else if(operationContent.includes('修改')){
        operationContent.includes('修改了密码') ? action = 'editPassWord' : action = 'edit'
      } else if(operationContent.includes('删除')){
        action = 'delete'
      }else if(operationContent.includes('启用')){
        action = 'start'
      }else if(operationContent.includes('禁用')){
        action = 'ban'
      }
      return (
        <i18n path={`common.record.dept.operate['${action}']`} tag="h5">
          <span place="operator">{executorStaffId ? this.renderUserName(executorName, executorStaffId, executorId) : this.renderUserName(userName, staffId, userId)}</span>
        </i18n>
      );
    },
    renderFaceIdRecord(record = {}) {
      let { userName, content, staffId, userId, action, taskId, taskNo } = record;
      return <span>
        <span place="operator">{this.renderUserName(userName, staffId, userId)}</span>
        {action === 'FACE_AUTH_PASSED' ? t('common.record.task.faceIdIsPass') : t('common.record.task.faceIdIsNotPass')}
        {this.renderTaskNo(taskNo, taskId)}
      </span>
    },
    // 提交自定义节点
    renderSubmitNodeRecord(record = {}) {
      let { userName, content, staffId, userId, taskNo } = record;
      return (
          <div>
            <span>{this.renderUserName(userName, staffId, userId)}</span>
            { this.$t('common.record.task.submitCustomNode', {btnName: content && content.buttonName, taskNo}) }
          </div>
      )
    },
    // 添加自定义节点负责人
    renderInsertNodeExecutorRecord(record = {}) {
      let { userName, content, staffId, userId, taskNo } = record;
      let users = []
      try {
        users = JSON.parse(content.insertUserList)
      } catch (e) {return []}

      return (
          <div>
            <span>{this.renderUserName(userName, staffId, userId)}</span>
            <i18n path="common.record.task.insertCustomNodeUser" tag="span">
              <span place="users">
                { users.map((item, index)=> <span>{index!==0 && ','}{this.renderUserName(item.displayName, item.staffId, item.userId)}</span>) }
              </span>
              <span place="nodeName">{ content && content.nodeName }</span>
              <span place="taskNo">{ taskNo }</span>
            </i18n>
          </div>
      )
    },
    // 添加自定义节点负责人
    renderDeleteNodeExecutorRecord(record = {}) {
      let { userName, content, staffId, userId, taskNo } = record;
      let users = []
      try {
        users = JSON.parse(content.deleteUserList)
      } catch (e) {return []}

      return (
          <div>
            <span>{this.renderUserName(userName, staffId, userId)}</span>
            <i18n path="common.record.task.deleteCustomNodeUser" tag="span">
              <span place="users">
                { users.map((item, index)=> <span>{index!==0 && ','}{this.renderUserName(item.displayName, item.staffId, item.userId)}</span>) }
              </span>
              <span place="nodeName">{ content && content.nodeName }</span>
              <span place="taskNo">{ taskNo }</span>
            </i18n>
          </div>
      )
    },
    /** 根据记录的action渲染对应的内容，支持jsx和render函数 */
    renderRecord(h, record) {
      let { action, userName, content, attachments, taskNo, taskId, staffId, userId } = record;

      if (action == '指派' || action == '转派')
        return this.renderAllotDom(record);
      if (action == '开始' || action == '完成')
        return this.renderStartOrFinishDom(record);
      if (action == '出发') return this.renderSetOutDom(record)
      if (action == '编辑回执') return this.renderReceiptEditDom(record);
      if (action == '添加') return this.renderActionRemarkDom(h, record);
      if (action == '留言') return this.renderLeaveMessageDom(h, record);
      if (action == '发布') return this.renderReleaseTaksPoolDom(record);
      if (action == '接受') return this.renderTaskAcceptDom(record);
      if (action == '新建') return this.renderTaskCreatetDom(record);
      if (action === 'API新建') return this.renderApiCreateDom(record);
      if (action === '计划任务新建')
        return this.renderPlanTaskCreateDom(record);
      if (action === '审批') return this.renderTaskApproveDom(record);
      if (action === '卡片') return this.renderTaskCardDom(record);
      if (action === '自动分配') return this.renderTaskAutoAllotDom(record);
      if (action === '自动分配失败')
        return this.renderTaskAutoAllotFailDom(record);
      if (action === '自动派单') return this.renderTaskAutoDispatchDom(record);
      if (action === '超时') return this.renderTaskTimeoutDom(record);
      if (action === '已超时') return this.renderTaskTimeoutdDom(record);
      if (action === '修改') return this.renderTaskEditDom(record);
      if (action === '转交') return this.renderTaskTransferDom(record);
      if (action === '暂停') return this.renderTaskPausedDom(record);
      if (action === '回访短信') return this.renderTaskCodeReviewDom(record);
      if (action === '回访' || action === '回访并关闭')
        return this.renderTaskReviewDom(record);
      if (action === '修改结算') return this.renderTaskBalanceDom(record);
      if (action === '服务报告') return this.renderTaskServiceReportDom(record);
      if (action == '电话日志') return this.renderPhoneLogDom(record);
      if (action == '支付') return this.renderTaskPaymentDom(record);
      if (action == '审核转交')
        return this.renderTaskApproveTransferDom(record);
      if (action == '备件清单' || action == '服务清单')
        return this.renderSparepartAndServiceListDom(record);
      if (action === '自定义异常') return this.abnormalRender(record);
      if (action === '更新状态') return this.renderWorkingStatusDom(record);
      if (action === '更新位置') return this.renderUpdateAddressRecord(record);
      if (action === 'user_operate_log') return this.renderOperateLog(record);
      if (action === '连接器to') return this.renderConnectorTo(record)
      if (action === '连接器from') return this.renderConnectorFrom(record)
      if (action === '触发器to') return this.renderTriggerTo(record)
      if (action === '触发器from') return this.renderTriggerFrom(record)
      if (action === 'FACE_AUTH_PASSED') return this.renderFaceIdRecord(record)
      if (action === 'FACE_AUTH_FAILED') return  this.renderFaceIdRecord(record)
      if (action === 'submitNode') return  this.renderSubmitNodeRecord(record)
      if (action === 'insertNodeExecutor') return  this.renderInsertNodeExecutorRecord(record)
      if (action === 'deleteNodeExecutor') return  this.renderDeleteNodeExecutorRecord(record)

      const {
        isGoBack,
        synergy,
        updateType,
        updateContent,
        customReason,
        customExceptionReason
      } = content;
      const reason = customExceptionReason || customReason;
      return [
        <h5>
          <i18n path="department.deptRecords.renderBaseTaskAction">
            <span place="user">{this.renderUserName(userName, staffId, userId)}</span>
            <span place="action">{translateAction(action)}</span>
            <span place="task">{this.renderTaskNo(taskNo, taskId)}</span>
          </i18n>
        </h5>,
        synergy && <div>{this.$t('common.fields.synergies.displayName')}：{this.renderSynergyName(synergy, content.synergyStaffId)}</div>,
        updateType == 'tRecord' && reason && (
          <div>{`${translateAction(action)}${this.$t('common.base.reason')}：${reason}`}</div>
        ),
        updateType == 'tRecord' && updateContent && (
          <div>{this.$t('common.base.detailsReason')}：<biz-comment-html html={updateContent}></biz-comment-html></div>
        ),
        isGoBack !== undefined && (
          <div>
            {isGoBack !== null
              ? isGoBack == '1' ? this.$t('common.record.task.partBackUp.back') : this.$t('common.record.task.partBackUp.notBack')
              : ''}
          </div>
        ),
        createAttachmentDom(h, attachments),
      ];
    },
    renderUserName(userName, staffId, userId){
      return (
        <recordUserName userName={userName} staffId={staffId} userId={userId} />
      )
    },
    renderSynergyName(synergy, synergyStaffId){
      if(isOpenData && synergy != '自动审批' && synergyStaffId) {
        const sids = synergyStaffId.split(',')
        if(sids.length) return sids.map(item=><open-data key={item} type="userName" openid={item}></open-data>)
      }
      return synergy
    },
    async searchRecord() {
      const dateInfo = this.initDate;

      try {
        this.recordLoading = true;

        this.params.pageNum = 1;
        let params = {
          ...this.params,
          ...dateInfo,
        }
        if(this.isFromUserView) {
          params.userId = this.detailId
        }else {
          params.tagId = this.detailId
        }
        let data = await this.fetchRecord(params);
        const list = data?.result?.list || []
        const isLoadAll = list.length < 15

        this.showLoadmore = !isLoadAll;

        this.recordLoading = false;
        this.recordPage.list = [];
        this.recordPage.merge(data.result);
      } catch (error) {
        console.warn('searchRecord -> error', error);
      }
    },
    // 类型切换
    selectChange(e) {
      let obj = {
        pageNum: 1,
        pageSize: 15
      }

      switch (e) {
        case "state":
          obj.searchByRemark = 0;
          this.exportAction = `/security/user/workState/export?userId=${this.detailId}`;
          break;
        case "type":
          obj.searchByRemark = 1;
          this.exportAction = `/security/user/taskRecord/export?userId=${this.detailId}&searchByRemark=1`;
          break;
        case "log":
          obj.searchByRemark = 0;
          obj.ignoreActionList = ['user_operate_log'];
          this.exportAction = `/security/user/taskRecord/export?userId=${this.detailId}&searchByRemark=0`;
          break;
        case "location":
          obj.searchByArea = 1;
          this.exportAction = `/security/user/taskRecord/export?userId=${this.detailId}&searchByArea=1`;
          break;
        case "userRecord":
          obj.action = 'user_operate_log';
          break;
        default:
          break;
      }
      this.showLoadmore = true;
      this.params = obj;
      this.searchRecord();
    },
    exportRecords(){
      // location.href = this.exportAction;
      {/* const { createTimeStart, createTimeEnd } = this.initDate */}
      this.portUrl = this.initDate.createTimeStart ? `${this.exportAction}&${objectToUrlParams(this.initDate)}` : this.exportAction;
      this.exportResponseHandler();
      // this.$http.get(this.portUrl, {}, { responseType: 'blob' })
      //   .then(this.exportResponseHandler(res,portUrl))
      //   .catch(err => console.error(err));
    },
    exportResponseHandler(blob) {
      let link = document.createElement('a');
      // let data = [];
      // data.push(blob);
      // let url = URL.createObjectURL(new Blob(data));
      let fileName = '';
      // 纯客服云版本导出文件名处理
      if (this._isNotShowTaskModule) {
        fileName = `${this.displayName}-${formatDate(new Date(), 'YYYY-MM-DD')}${this.$t('common.base.workState')}.xlsx`;
        console.log(fileName, 'fileName')
      } else {
        fileName = `${this.displayName}-${formatDate(new Date(), 'YYYY-MM-DD')}${this.portUrl.indexOf('workState') > -1 ? this.$t('common.base.workState') : this.$t('common.base.taskLog')}.xlsx`;
      }
      link.download = fileName;
      link.href = this.portUrl;
      this.$refs.bridge.appendChild(link);
      link.click();
      setTimeout(() => {
        // URL.revokeObjectURL(url);
        this.$refs.bridge.removeChild(link);
      }, 150);
    }
  },
};
</script>
<style lang="scss">
.form-view-row-content-address {
  cursor: pointer;
}
div.form-view-row-content-address > span {
  display: block;
}
.form-view-row-content-address:hover {
  color: $color-primary-light-6;
}
.task-timeline {
  padding-top: 15px;
  flex: 1;
  padding-right: 15px;
  .private {
    @include fontColor();
  }
  .task-no-link {
    color: $color-primary;
    cursor: pointer;
  }
}
.task-position-exception,
.task-record-fail {
  color: #f0ad4e;
}

.task-info-record {
  height: 100%;
  display: flex;
  flex-flow: column nowrap;
  background-color: #fff;
}

.progress-content {
  padding: 16px;
  .page-right-search {
    display: flex;
    flex-direction: column;
    > div {
      display: flex;
      align-items: center;
      margin-bottom: 12px;
      > span {
        min-width: 70px;
      }
      > div {
        flex: 1;
      }
    }
  }
  .page-right-search-user {
    flex-direction: row;
    div {
      flex: 1;
    }
    button {
      margin: 0 0 12px 12px;
    }
    .search-label{
      color:#595959;
    }
  }
}
</style>
<style lang="scss">
.min-w-250{
  min-width:250px
}
.progress-content{
  .el-dialog__headerbtn {
    top: 0;
  }
  .base-modal-content {
    display: flex;
    #container {
      flex: 1;
      height: 100%;
      min-height: 400px;
    }
    .track-container {
      width: 240px;
      height: 400px;
      overflow-y: auto;
    }
    .el-radio-group {
      padding: 0 12px;
      border-left: 1px solid #E0E6ED;
      white-space: nowrap;
    }
  }
}

.track-map-icon {
  width: 23px;
  cursor: pointer;
}
.btn-show-track-map {
  font-weight: 600;
  padding: 5px;
  display: inline-block;
  color: #fff;
  background-color: #3c8dbc;
  border-radius: 4px;
  cursor: pointer;
}
.btn-show-track-map:hover {
  color: #fff;
  text-decoration: none;
}
.track-map-inner-title {
  font-size: 12px;
  color: #333333;
  line-height: 18px;
  margin-bottom: 12px;
}
.track-map-inner-row {
  display: flex;
  flex-wrap: nowrap;
}
.track-map-inner-label {
  font-size: 12px;
  color: #999999;
  line-height: 18px;
  flex-shrink: 0;
}
.track-map-inner-value {
  font-size: 12px;
  color: #606266;
  line-height: 18px;
}
.track-map-inner-link {
  font-size: 12px;
  color: #3c8dbc;
  line-height: 18px;
  text-decoration: none;
  cursor: pointer;
}
.track-map-marker-icon-dom {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 19px;
  height: 27px;
  background-size: 100% 100% !important;
}
.track-map-marker-icon-index {
  font-size: 12px;
  color: #ffffff;
  margin-bottom: 8px;
}
.track-map-dialog {
  width: 70% !important;
  box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.04), 0px 2px 4px 0px rgba(0, 0, 0, 0.12);
  border: 1px solid rgba(211, 220, 230, 1);
}
.track-modal-header {
  height: 60px;
  padding: 0 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid #E0E6ED !important;
}
#trackMapTitle {
  font-size: 16px;
  line-height: 1;
  color: #1f2d3d;
  font-weight: 600;
}
.track-modal-close {
  outline: none;
}
.box-body {
  padding: 0;
}
.track-map-adapter-view {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 46.2%;
}
.track-map-proxy-view {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: nowrap;
}
.track-map-instance {
  width: 100%;
  height: 100%;
}

.track-map-right-container {
  position: relative;
  display: flex;
  flex-direction: column;
  flex-grow: 0;
  width: 340px;
  height: 100%;
  border-left: 1px solid #E0E6ED;
}

.track-map-switcher-view {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 15px 0;
  border-bottom: 1px solid #eeeeee;
  flex-shrink: 0;
}

.track-map-switcher-btn {
  width: 86px;
  height: 36px;
  background-color: #ffffff;
  color: #333333;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  outline: none;
  margin: 0;
  border: 1px solid rgba(220,223,230,1);
  transition-duration: .3s;
  cursor: pointer;
}

#trackMapOrderLocBtn {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;

}

#trackMapWorkStateBtn {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
  border-left: 1px solid transparent;
}

.track-map-switcher-btn-active {
  color: #ffffff;
  background-color: #00ac98;
  border: 1px solid #00ac98;
}

.track-map-list-container {
  position: relative;
  width: 100%;
  height: 100%;
  /*padding: 0 5px 0 25px;*/
  overflow: auto;
  margin-top: 68px;
}

.track-map-list-item {
  position: relative;
  margin-bottom: 0;
  padding-left: 20px;
  cursor: pointer;
  background-color: #ffffff;
}

.track-map-list-item:hover {
  background-color: #f5f7fa;
}

.track-map-list-item:hover .track-map-list-icon-view::before {
  background-color: #f5f7fa !important;
}

.track-map-list-item:hover .track-map-list-item-inner::before {
  background-color: #f5f7fa !important;
}

.track-map-list-item-inner {
  position: relative;
  border-left: 1px dashed #c0ccda;
  padding: 10px 10px 0 20px;
}

.track-map-list-item-active .track-map-l-i-title {
  color: $color-primary;
}

.track-map-l-i-title {
  position: relative;
  font-size: 12px;
  color: #333333;
  font-weight: 500;
  margin-bottom: 12px;
  transition-duration: .3s;
}

.track-map-list-icon-view {
  position: absolute;
  left: -9px;
  top: 10px;
  width: 18px;
  height: 26px;
  background: url('../../../../assets/img/trackmap/trackmap_location_index_icon.png');
  background-size: 100% 100%;
  text-align: center;
  font-size: 12px;
  color: #ffffff;
  line-height: 17px;
  font-weight: 400;
  /*transition-duration: .3s;*/
}

.track-map-l-i-row {
  display: flex;
  flex-wrap: nowrap;
  line-height: 18px;
}

.track-map-l-i-key {
  font-size: 12px;
  line-height: 18px;
  color: #999999;
  flex-shrink: 0;
}

.track-map-l-i-value {
  font-size: 12px;
  line-height: 18px;
  color: #606266;
}

.track-map-l-i-link {
  font-size: 12px;
  line-height: 18px;
  color: #3c8dbc;
  text-decoration: none;
}

.track-map-list-item:first-of-type .track-map-list-icon-view::before {
  content: '';
  position: absolute;
  height: 10px; /* 与padding-top统一 */
  width: 100%;
  left: 0;
  top: -10px;
  background-color: #ffffff;
}

.track-map-list-item:last-of-type .track-map-list-item-inner::before {
  content: '';
  position: absolute;
  /* 36px: padding-top: 10px, icon-height: 26px; */
  top: 36px;
  height: calc(100% - 36px);
  width: 2px;
  left: -1px;
  background-color: #ffffff;
}

.track-map-l-i-line {
  height: 1px;
  width: 100%;
  background-color: #eeeeee;
  margin: 10px 0 0;
}

.base-export-bridge {
  position: absolute;
  top: -1000px;
  left: -1000px;

  a {
    display: block;
    border: none;
    outline: none;
    width: 0;
    height: 0;
  }
}
</style>
